package com.cono.html


class Html(val data: String)

val render = { html: Html -> html.data }

class Structure(val data: String)


fun append(vararg items: Structure): Structure {
    return Structure(items.joinToString("") { it.data })
}

val el = { tag: String, content: String ->
    "<$tag>$content</$tag>"
}

val p = { content: String -> Structure(el("p", content)) }
val h1 = { content: String -> Structure(el("h1", content)) }

val html = { title: String, content: Structure ->
    Html(
        el(
            "html",
            el("head", el("title", title)) + el("body", content.data)
        )
    )
}

val ul = { items: Array<Structure> ->
    Structure(el("ul", items.joinToString("") { el("li", it.data) }))
}

val ol = { items: Array<Structure> ->
    Structure(el("ol", items.joinToString("") { el("li", it.data) }))
}

val code = { item: String ->
    Structure(el("pre", escape(item)))
}

fun escape(data: String): String {
    val target = ArrayList<Char>()
    val append_ = { str: String, t: ArrayList<Char> -> t.addAll(str.toCharArray().toList()) }
    val escapeChar = { c: Char ->
        when (c) {
            '<' -> "&lt;"
            '>' -> "&gt;"
            '&' -> "&amp;"
            '"' -> "&quot;"
            '\'' -> "&#39;"
            else -> c + ""
        }
    }

    data.toCharArray().toList().forEach { append_(escapeChar(it), target) }
    return target.joinToString("")
}

fun main() {
    val myhtml = html(
        "My title", append(
            h1("Heading"),
            p("Paragraph #1<"),
            p("Paragraph #2"),
            code("println(hallo)")
        )
    )

    println(render(myhtml))
}